/**
 * Copyright (c) 2009 blurredVision
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
 * associated documentation files (the "Software"), to deal in the Software without restriction, 
 * including without limitation the rights to use, copy, modify, merge, publish, distribute, 
 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all copies or 
 * substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT 
 * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT 
 * OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
#pragma once

#include "geom/Vector.h"
#include "IResource.h"

#define LODLEVEL 5

namespace model {

/// The vertex data for the mesh
struct sMeshVertex
{
	math::Vector3 position;		///< position vector
	math::Vector3 normal;		///< normal vector
	math::Vector2f tex0;		///< texture coords
};

struct sCompleteMeshVertex
{
	math::Vector3 position;		///< position vector
	math::Vector3 normal;		///< normal vector
	math::Vector3 tangent;		///< tangent vector (basis vector s)
	math::Vector3 binormal;		///< binormal vector (basis vector t)
	math::Vector2f tex0;		///< texture coords
};

/// A face for the mesh
struct sMeshFace {
	unsigned int   vertexIndex[3];	///< vertex indices
	math::Vector3  normals[3];		///< face normals at the vertex positions
	math::Vector2f texCoord0[3];	///< texture coordinates at the vertex positions
};

/**
 * \ingroup CoreEngine
 *
 * The IMeshGeometry interface.<br>
 * Stores the hardware specific vertex data of an IMesh.
 *
 * \date 04-02-2007
 *
 * \author juckel
 *
 */
class DLL_EXPORT IMeshGeometry
	: public IResource
{
public:
	IMeshGeometry(void);
	virtual ~IMeshGeometry(void);

	/// Return the number of vertices
	const unsigned int getNumVertices() const;

	/// Return the number of mesh faces
	const unsigned int getNumFaces() const;

	/// Return a pointer to the mesh vertex stucture. Duplicates of vertices can be present
	sMeshVertex* getMeshVertices();

	/// Return a pointer to the unique vertices
	math::Vector3* getRawVertices() { return m_pUniqueVertices; };

	/// Return the number of unique vertices
	const unsigned int getNumRawVertices() const { return m_uiNumUniqueVertices; };

	/// Return a pointer to the mesh faces
	sMeshFace* getMeshFaces();

	///Altjohann
	/// Returns a pointer to the reverted Indices
	unsigned int* getInvertedIndices();

	/// Load a mesh. Called by IMesh::load()
	bool load(FILE *file);

	/// Draw the mesh. Needs hardware implementation.
	virtual void draw(unsigned int lodLevel) = 0;

	virtual unsigned int getType() { return RESTYPE_MESHGEOMETRY; };

	friend class IMesh;
protected:
	virtual bool initMesh() = 0;

	unsigned int   m_uiNumFaces;			///< Number of faces
	sMeshFace     *m_pFaces;				///< The faces
	unsigned int   m_uiNumVertices;			///< The number of vertices. They can be accessed by the face's vertexIndex
	sMeshVertex   *m_pVertices;				///< The vertices
	math::Vector3 *m_pUniqueVertices;
	unsigned int   m_uiNumUniqueVertices;

	unsigned int   m_uiNumLODVertices[LODLEVEL];	///< The number of vertices per LOD. There are 3 LODs
	unsigned int   lastLOD;

	//Altjohann
	unsigned int*	m_pIndicesInverted;

};

} // namespace